package com.svms.service.dml.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;

import com.svms.domain.dao.SvmsMovementMapper;
import com.svms.domain.dao.SvmsVehicleSpareMapper;
import com.svms.model.SvmsMovement;
import com.svms.model.SvmsVehicleSpare;
import com.svms.model.SvmsVehicleSpareExample;
import com.svms.model.SvmsVehicleSpareExample.Criteria;
import com.svms.service.constants.SvmsStatusCodes;
import com.svms.service.dml.iface.MovementDMLIF;
import com.svms.service.mapper.MovementMapper;
import com.svms.service.mapper.VehicleSpareMapper;
import com.svms.service.util.NumberGeneratorUtils;
import com.svms.service.validators.MovementValidator;
import com.svms.service.vo.MovementVO;
import com.svms.service.vo.ResultCodeVO;
import com.svms.service.vo.VehicleSpareVO;

public class MovementDML implements MovementDMLIF {

	private static Logger logger = Logger.getLogger(MovementDML.class);
	private SvmsMovement svmsMovement;
	private MovementValidator movementValidator;

	public MovementValidator getMovementValidator() {
		return movementValidator;
	}

	public void setMovementValidator(MovementValidator movementValidator) {
		this.movementValidator = movementValidator;
	}

	@Autowired
	private SvmsMovementMapper svmsMovementMapper;
	@Autowired
	private SvmsVehicleSpareMapper svmsVehicleSpareMapper;

	public ResultCodeVO resultSet;

	@Override
	public MovementVO insertNewMovement(MovementVO movement) {
		logger.debug("inside insertNewMovement  method");

		// TODO Check Duplicates before inserting

		System.out.println("========================================");
		System.out.println(movement);
		System.out.println("========================================");
		ResultCodeVO resultCode = new ResultCodeVO();
		try {
			movement.setMovementId(String.valueOf(NumberGeneratorUtils
					.generateMovemenrId()));

			SvmsMovement svmsMovement = MovementMapper.serviceToDml(movement);

			int successCode = svmsMovementMapper.insert(svmsMovement);
			if (successCode == 0) {
				resultCode
						.addErrorDetail(SvmsStatusCodes.INSERTING_VEHICLE_INTO_DATABASE_FAILED);
				movement.setResultCode(resultCode);
			} else {

				updateVehicleSpareDetails(movement);

			}
			logger.debug("exiting from insertNewMovement method");

		} catch (Exception e) {
			e.printStackTrace();
			logger.error("Error occured in insertNewMovement method");
			resultCode.addErrorDetail(SvmsStatusCodes.DAO_EXCEPTION);
			movement.setResultCode(resultCode);
		}
		return movement;
	}

	private void updateVehicleSpareDetails(MovementVO movement) {

		VehicleSpareVO vehicleSpareVO = new VehicleSpareVO();
		vehicleSpareVO.setVehicleVO(movement.getVehicleVO());

		SvmsVehicleSpareExample svmsVehicleSpareExample = new SvmsVehicleSpareExample();
		Criteria criteria = svmsVehicleSpareExample.createCriteria();

		criteria.andVehicleIdEqualTo(movement.getVehicleVO().getVehicleId());

		List<SvmsVehicleSpare> svmsSpareVOs = svmsVehicleSpareMapper
				.selectByExample(svmsVehicleSpareExample);

		for (SvmsVehicleSpare svmsVehicleSpare : svmsSpareVOs) {
			VehicleSpareVO spareVO = VehicleSpareMapper
					.dmlToService(svmsVehicleSpare);

			// Updating the distance traveled
			spareVO.setDistanceTraveled(String.valueOf(Integer.valueOf(spareVO
					.getDistanceTraveled())
					+ Integer.valueOf(movement.getDistanceTraveled())));

			// Updating days traveled

			long tripDaysCount = (movement.getEndDate().getTime() - movement
					.getStartDate().getTime()) / (24 * 60 * 60 * 1000);

			spareVO.setDaysTraveled(String.valueOf((Integer.valueOf(spareVO
					.getDaysTraveled()) + tripDaysCount)));

			int successCode = svmsVehicleSpareMapper
					.updateByPrimaryKey(VehicleSpareMapper
							.serviceToDml(spareVO));

			System.out.println("%%%%%%%%%%%%%%%%%%%%%%%%%%%");

			if (successCode == 0) {
				System.out.println("Updating VehicleSpareVO in DB failed ");
			} else {
				System.out.println("Updating VehicleSpareVO in DB is success");
			}

		}

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.svms.service.MovementDMLIF#deleteMovement(com.svms.vo.MovementVO)
	 */
	@Override
	public MovementVO deleteMovement(MovementVO movement) {
		logger.debug("inside deleteMovement method");
		System.out.println("===================================");
		System.out.println(movement);
		System.out.println("===================================");
		try {
			if (svmsMovement == null) {
				svmsMovement = new SvmsMovement();
			}
			resultSet = new ResultCodeVO();

			int successIndicator = svmsMovementMapper
					.deleteByPrimaryKey(Integer.valueOf(movement
							.getMovementId()));

			if (successIndicator == 1) {
				/*
				 * resultSet.result.put("Result", "Success");
				 * resultSet.result.put("Message", "Movement Data of Vehicle : "
				 * + movement.getVehicleVO().getVehicleId() +
				 * "  Deleted successfully");
				 */
				movement.setResultCode(resultSet);
			} else {
				/*
				 * resultSet.result.put("Result", "Fail");
				 * resultSet.result.put("Message", "Movement Data of Vehicle : "
				 * + movement.getVehicleVO().getVehicleId() +
				 * "  was a failure");
				 */
				movement.setResultCode(resultSet);
			}

			logger.debug("exiting from deleteMovement method");
		} catch (Exception e) {
			logger.error("Error occured in deleteMovement method");
			/*
			 * resultSet.result.put("Result", "Fail");
			 * resultSet.result.put("Message", e.getMessage());
			 */
			movement.setResultCode(resultSet);
			return movement;
		}
		return movement;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.svms.service.MovementDMLIF#getMovement(com.svms.vo.MovementVO)
	 */
	@Override
	public MovementVO getMovement(MovementVO movement) {
		logger.debug("inside getMovement method");
		MovementVO movementVO = null;
		if (svmsMovement == null) {
			svmsMovement = new SvmsMovement();
		}
		try {
			SvmsMovement results = svmsMovementMapper
					.selectByPrimaryKey(Integer.valueOf(movement
							.getMovementId()));
			logger.debug("exiting from getMovement method");
			if (results != null) {
				movementVO = MovementMapper.dmlToService(results);
			}

		} catch (Exception e) {
			logger.error("Error occured in getMovement method");
			e.printStackTrace();
			return movementVO;
		}
		return movementVO;
	}

	@Override
	public List<MovementVO> getMovementList() {
		logger.debug("inside getMovementList method");
		List<SvmsMovement> resultSet = null;
		List<MovementVO> movementList = new ArrayList<MovementVO>();

		try {
			resultSet = svmsMovementMapper.getEntireTableData();
			for (SvmsMovement svmsMovement : resultSet) {
				movementList.add(MovementMapper.dmlToService(svmsMovement));
			}

			logger.debug("exiting from getMovementList method");

		} catch (Exception e) {
			logger.error("Error occured in getMovementList method");
			e.printStackTrace();
			return movementList;
		}
		return movementList;
	}

	@Override
	public MovementVO editMovement(MovementVO movement) {

		if (svmsMovement == null) {
			svmsMovement = new SvmsMovement();
		}
		resultSet = new ResultCodeVO();

		svmsMovement.setVehicleId(Long.valueOf(movement.getVehicleVO()
				.getVehicleId()));
		svmsMovement.setUpdatedTime(new Date());
		svmsMovement.setEndDate(movement.getEndDate());
		svmsMovement.setStartDate(movement.getStartDate());
		svmsMovement.setStartPlace(movement.getStartPlace());
		svmsMovement.setEndPlace(movement.getEndPlace());
		svmsMovement.setMovememtId(Integer.valueOf(movement.getMovementId()));
		svmsMovement.setStuffingPlace(movement.getStuffingPlace());
		svmsMovement.setUpdateBy("admin");
		svmsMovement.setTripDistance(Integer.valueOf(movement
				.getDistanceTraveled()));

		int successCode = svmsMovementMapper.updateByPrimaryKey(svmsMovement);

		if (successCode == 0) {
			
		} else {
			
			//TODO  Update should be done when 
			
			updateVehicleSpareDetails(movement);
		}

		return movement;
	}
}
